有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

接口中的java继承

我有两个界面:

public interface EventListener {

    <T extends Data> T modify(T data);

    public static class Data {

    }
}

以及:

public interface ServerInfoEventListener extends EventListener {

    // This works
    @Override ServerInfoData modify(Data data);

    // This doesn't work!
    @Override ServerInfoData modify(ServerInfoData data);

    public static class ServerInfoData extends Data {
        public ServerInfoData(String motd, int playerCount, int maxPlayers) {
            this.motd = motd;
            this.playerCount = playerCount;
            this.maxPlayers = maxPlayers;
        }
        public String motd;
        public int playerCount;
        public int maxPlayers;
    }
}

从评论中可以看出,modify(ServerInfoData data)没有编译。为什么不呢?我该怎么解决呢ServerInfoData扩展了{},所以它应该可以工作,对吗


共 (4) 个答案

  1. # 1 楼答案

    正如在接口EventListener方法modify中声明的那样,需要Data(或任何子类)类型的参数

    ServerInfoData modify(ServerInfoData data);接受类型为ServerInfoData的参数,但接口中的定义表示“它应该接受任何碰巧具有类型为Data的超类的参数”,这意味着子类中方法的参数类型与接口中声明的参数类型不匹配

    考虑这个例子:

    public static class AnotherData extends Data {
        // Whatever
    }
    
    public void main() {
        EventListener el = new ServerInfoEventListener() {...};
        el.modify(new AnotherData()); // We have a problem
    }
    

    问题是:没有方法实现来处理AnotherData,但应该有,因为EventListener这样说ServerInfoData modify(ServerInfoData data)不能接受,因为AnotherData不是ServerInfoData的实例

    希望这有帮助

  2. # 2 楼答案

    我无法充分解释它无法工作的具体技术原因,但我可以解释修复方法

    接口应该在类级别而不是方法级别使用泛型。我们还需要将Data移出EventListener(由于creation deadlock):

    class Data
    {
        //...
    }
    
    interface EventListener<T extends Data>
    {
        T modify(T data);
    }
    
    interface ServerInfoEventListener extends EventListener<ServerInfoEventListener.ServerInfoData>
    {
        @Override ServerInfoData modify(ServerInfoData data);
    
        class ServerInfoData extends Data {
            //...
        }
    }
    
    class ServerInfoEventListenerImpl implements ServerInfoEventListener
    {
        @Override
        public ServerInfoData modify(final ServerInfoData data)
        {
            return null;
        }
    }
    
  3. # 3 楼答案

    @Override ServerInfoData modify(ServerInfoData data)
    

    不起作用,因为它实际上不重写EventListener.modify,因为它不接受Data的任何其他子类,而不是ServerInfoData(和子类)

    您要么必须处理所有Data类型,要么使接口本身通用,而不仅仅是一种方法:

    public interface EventListener<T extends Data> {
        T modify(T data);
    }
    
    public interface ServerInfoEventListener extends EventListener<ServerInfoData> {
        @Override ServerInfoData modify(ServerInfoData data);
    }
    
  4. # 4 楼答案

    重写超级方法时,不能缩小泛型类型的范围

    <T extends Data> T modify(T data);
    

    这个来自接口的方法接受DataData的任何子类

    但当你覆盖它时,就像:

    @Override 
    ServerInfoData modify(ServerInfoData data);
    

    然后,您的方法不能与扩展Data类的ServerInfoData类同级,因此它会破坏重写的约定